package com.lq.learningTest.AnnotationTest;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class FileUtils {
    // 静态方法：根据文件夹对象，返回其中所有 .class 文件的全限定类名列表，包括子文件夹中的文件
    public static List<String> getAllClassName(File file) {
        // 1. 创建一个集合，用于存储所有 .class 文件的“绝对路径”
        List<String> classPaths = new ArrayList<>();

        // 2. 递归查找 file 路径下的所有 .class 文件，填充到 classPaths 列表中
        findAll(file.getAbsolutePath(),classPaths);
        /*
     3. 将绝对路径转换成全限定类名，例如：
        D:\project\out\production\xxx\com\example\MyClass.class
        → com.example.MyClass

        转换方式：
        - 去掉根路径前缀
        - 替换文件分隔符为点号
        - 去掉“.class”后缀
     */
        //使用流水线操作，最终再处理成List集合
        return classPaths.stream().map(path -> {
            String fileName = file.getAbsolutePath();// 根路径

            return path.replace(fileName + "\\", "")// 去除根目录前缀
                    .replaceAll("\\\\",".")// 替换路径分隔符为 .
                    .replace(".class","");// 去除 .class 后缀
        }).collect(Collectors.toList());
    }


    // 私有辅助方法：递归扫描路径下所有 .class 文件
    private static void findAll(String path,List<String> classPathList) {
        // 当前目录对象
        File file = new File(path);
        // 过滤出目录或包含“.class”关键字的文件，这里的f是文件所处文件夹的路径，n是文件夹下面的内容
        File[] list = file.listFiles((f, n) -> new File(f, n).isDirectory() || n.contains(".class"));
        //如果当前项目是一个子目录（isDirectory() 为 true），则保留它 —— 用于递归。
        //如果当前文件名包含 ".class"，也保留它 —— 用于加载 class 文件。

        /*
        等价于：
        File[] list =file.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return new File(dir, name).isDirectory() || name.contains(".class");
            }
        });
         */

        if (list == null || list.length == 0) {
            return;
        }
        for (File parent : list) {
            // 看看是不是一个文件夹，如果是
            if (parent.isDirectory()) {
                // 递归，检测子文件夹
                findAll(parent.getAbsolutePath(),classPathList);
            } else {
                // 如果不是，加入到classPathList中
                classPathList.add(parent.getAbsolutePath());
            }
        }
    }
}
